<script setup lang="ts">
import { onMounted, getCurrentInstance, ref, watch } from "vue";
import { CameraFilled, Plus } from "@element-plus/icons-vue";
import type { UploadFile, UploadInstance } from "element-plus";
import { useUserStore } from "@/store/modules/user.ts";
import { ElMessage } from "element-plus";
import { reqUploadImage } from "@/api/credit/peasants/pea-message";
import { reqUpload } from "@/api/credit/peasants/pea-message/type";

/*接收参数信息*/
/*接收父组件传来的参数*/
const props = defineProps({
  Url: {
    type: String,
    required: true
  },
  title: {
    type: String,
    default: "请上传照片"
  }
});
let $emit = defineEmits(["update:Url"]);
/*要展示的照片列表*/
const fileListRef = ref<UploadFile[]>([]);
/*大图查看*/
const dialogImageUrl = ref("");
const dialogVisible = ref(false);
const acceptedImageTypes = ".png,.jpg,.jpeg"; /*允许的类型*/
/*头像地址*/
const baseUrl = import.meta.env.VITE_APP_BASE_API; /*获取请求的ip地址*/
/*手动上传*/
const uploadRef = ref<UploadInstance>();
/*文件改变时函数,只第一次改变有效*/
const handleOnChange = (uploadFile: UploadFile) => {
  if (fileListRef.value.length >= 1) {
    fileListRef.value.pop();
  }
  console.log("文件改变时函数,只第一次改变有效...");
  console.log(uploadFile);
  if (uploadFile) {
    fileListRef.value.push(uploadFile);
  }
};

//////////////////////////////////////////////////////////////
const { proxy }: any = getCurrentInstance();
// 相机基本数据
/*相机对话框开关*/
const centerDialogVisible = ref(false);
const disabled = ref(false);
const video = ref<HTMLVideoElement | null>();
const canvas = ref<HTMLCanvasElement | null>();


/*打开相机操作*/
const handleCenterDialogVisible = async () => {
  try {
    /*2. 打开相机*/
    await callCamera();
    /*1. 将对话框打开*/
    centerDialogVisible.value = true;
  } catch (error) {
    /*处理错误，如果callCamera()发生了异常*/
    console.error("Error while calling the camera:", error);
  }
};

/*开启摄像头*/
const callCamera = () => {
  navigator.mediaDevices
    .getUserMedia({
      video: true
    })
    .then((success) => {
      video.value.srcObject = success;
      video.value.play();
    })
    .catch((er: any) => {
      console.error("摄像头开启失败，请检查摄像头是否可用！" + er);
    });
};

/*拍照
 * 1. 将对话框关闭
 * 2. 将照片路径给返还出来
 * */
const uploadImg = async () => {
  let ctx = canvas.value.getContext("2d");
  ctx.drawImage(video.value, 0, 0, 640, 480);
  let imgBase64 = canvas.value.toDataURL("image/jpeg", 0.7);
  let str = imgBase64.replace("data:image/jpeg;base64,", "");
  let strLength = str.length;
  let fileLength = parseInt(strLength - (strLength / 8) * 2);
  let size = (fileLength / 1024).toFixed(2);

  // 将拍摄的照片添加到fileListRef中
  // 将照片数据转换为Blob对象
  const blob = dataURLtoBlob(imgBase64);

  // 创建File对象，注意第三个参数为文件名
  const file: File = new File([blob], new Date().getTime() + ".jpeg", {
    type: "image/jpeg"
  });

  // 清空canvas中的内容，以便下一次拍摄
  ctx.clearRect(0, 0, canvas.value.width, canvas.value.height);
  /*/!*拍完照照相机关闭*!/*/

  /*将file进行上传*/
  const form = new FormData();
  form.set("file", file);

  /*将file进行上传*/
  let result: reqUpload = await reqUploadImage(form);
  if (result.code === 200) {
    /*文件上传成功*/
    ElMessage.success("文件上传成功");
    /*将地址进行赋值即可*/
    $emit("update:Url", result.fileName);
    console.log(result.fileName);
    url.value = result.url;
    if (ListUrl.value.length > 0) {
      ListUrl.value.pop();
    }
    ListUrl.value.push(url.value);
    console.log("result", result);
    handleCloseDialogVisible();
  } else {
    ElMessage.info("文件上传失败请重试！！！");
  }
};

// 将Data URL转换为Blob对象
const dataURLtoBlob = (dataURL: any) => {
  const arr = dataURL.split(",");
  const mime = arr[0].match(/:(.*?);/)[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
};

/*关闭摄像头*/
const closeCamera = () => {
  try {
    if (!video.value.srcObject) return;
    let stream = video.value.srcObject;
    let tracks = stream.getTracks();
    tracks.forEach((track) => {
      track.stop();
    });
    video.value.srcObject = null;
  } catch (error) {
    console.error("关闭相机时出现错误：", error);
    // 在发生错误时，强制关闭相机
    if (video.value) {
      video.value.pause();
      video.value.srcObject = null;
    }
  }
};

/*关闭相机对话框*/
const handleCloseDialogVisible = () => {
  /*2. 关闭相机*/
  closeCamera();
  /*1. 将对话框进行隐藏*/
  centerDialogVisible.value = false;
};

/*上传的照片地址*/
const url = ref(null);
const ListUrl = ref([]);

/*自定义方法上传文件*/
const handlerUpload = async (data: any) => {
  console.log("自定义方法上传文件...");
  console.log(data);
  const file = data.file;
  const form = new FormData();
  form.set("file", file);
  /*将file进行上传*/
  let result: reqUpload = await reqUploadImage(form);
  if (result.code === 200) {
    /*文件上传成功*/
    ElMessage.success("文件上传成功");
    /*将地址进行赋值即可*/
    $emit("update:Url", result.fileName);
    if (ListUrl.value.length > 0) {
      ListUrl.value.pop();
    }
    url.value = result.url;
    ListUrl.value.push(result.url);
    console.log("result", result);
  } else {
    ElMessage.error(result.message);
  }
};

/*数据的绑定*/
watch(
  () => props.Url,
  () => {
    if (props.Url === "" || props.Url === null) {
      ListUrl.value = [];
      url.value = null;
      return;
    }
    url.value = baseUrl + props.Url;
    if (ListUrl.value.length > 0) {
      ListUrl.value.pop();
    }
    ListUrl.value.push(url.value);
  }
);

onMounted(() => {
  if (props.Url === "" || props.Url === null) {
    return;
  }
  url.value = baseUrl + props.Url;
  if (ListUrl.value.length > 0) {
    ListUrl.value.pop();
  }
  ListUrl.value.push(url.value);
});


// 上传文件超出限制
const handleOnExceed = () => {
  proxy.msgError("只能上传一张文件请删除后在进行上传...")

}
</script>

<script lang="ts">
/*上传一张照片的方法的封装*/
export default {
  name: "OneIdCardOther"
};
</script>

<template>
  <!--上传照片组件  -->
  <div class="demo-image__preview">
    <el-image
      style="width: 254px; height: 151px"
      :src="url"
      :zoom-rate="1.2"
      :preview-src-list="ListUrl"
      :initial-index="4"
      fit="cover"
    >
      <!--  上传文件默认标题    -->
      <template #placeholder>
        <div class="image-slot">
          <span class="image-text">{{ props.title }}</span>
        </div>
      </template>
      <!--      上传文件错误 展示-->
      <template #error>
        <div class="image-slot">
          <el-icon>
            <Picture />
          </el-icon>
        </div>
      </template>
    </el-image>
  </div>
  <!--直接添加  -->
  <div class="el-upload-all">
    <!--上传图片    -->
    <el-upload
      ref="uploadRef"
      action="#"
      :http-request="handlerUpload"
      list-type="picture-card"
      :accept="acceptedImageTypes"
      :auto-upload="true"
      :show-file-list="false"
      :on-exceed="handleOnExceed"
      :limit="1"
      class="el-upload-add"
    >
      <el-icon>
        <Plus />
      </el-icon>
    </el-upload>

    <!-- 拍照   -->
    <div class="el-image-dragger el-upload-p" @click="handleCenterDialogVisible">
      <el-icon>
        <CameraFilled class="el-icon" />
      </el-icon>
    </div>

    <el-dialog v-model="dialogVisible">
      <el-image style="width: 100%; height: 100%" :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
  </div>

  <!--拍照对话框  -->
  <el-dialog
    v-model="centerDialogVisible"
    title="拍照"
    destroy-on-close
    center
    v-loading="true"
    :before-close="handleCloseDialogVisible"
  >
    <span>
      <canvas ref="canvas" v-show="false" width="600" height="480"></canvas>
      <video ref="video" style="height: 100%; width: 100%" autoplay></video>
    </span>
    <!--    <div>
      <div style="width: 200px">
        <div
          v-for="(item, index) in videoArr"
          @click="setCurrentDevice(item.id)"
        >
          {{ item.label }}
        </div>
      </div>
    </div>-->
    <!--自定义对话框的尾部    -->
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="callCamera" style="margin-right: 10px"> 开启摄像头 </el-button>
        <el-button @click="changeDevice" style="margin-right: 10px"> 切换摄像头 </el-button>
        <el-button type="warning" @click="closeCamera">关闭摄像头</el-button>
        <el-button type="success" @click="uploadImg">拍照</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<style scoped lang="scss">
.demo-image__preview {
  margin: 10px 20px 10px 0px;
  text-align: center;
  border: dashed 2px var(--el-border-color);
  display: inline-block;
  width: 254px;
  height: 151px;
  box-sizing: border-box;
  vertical-align: top;
  overflow: hidden;

  .image-text {
    font-size: 20px;
  }

  .image-slot {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    background: var(--el-fill-color-light);
    color: var(--el-text-color-secondary);
    font-size: 30px;
  }

  .el-image {
    max-height: 151px;
    width: 100%;
    height: 151px;
  }
}

/*图片上传和拍照上传文件组合*/
.el-upload-all {
  display: flex;

  .el-upload-add {
    margin-right: 20px;
  }

  .el-upload-p {
    margin-right: 20px;
  }

  .el-button-upload {
    margin-right: 20px;
  }
}

.el-image-dragger {
  --el-upload-picture-card-size: 148px;
  background-color: var(--el-fill-color-lighter);
  border: 1px dashed var(--el-border-color-darker);
  border-radius: 6px;
  box-sizing: border-box;
  width: var(--el-upload-picture-card-size);
  height: var(--el-upload-picture-card-size);
  cursor: pointer;
  vertical-align: top;
  display: inline-flex;
  justify-content: center;
  align-items: center;

  /*样式el-icon样式*/
  .el-icon {
    height: 2em;
    width: 2em;
    opacity: 0.6;
  }
}

/*照片展示*/
.demo-image__error .image-slot {
  font-size: 30px;
}

.demo-image__error .image-slot .el-icon {
  font-size: 30px;
}

.demo-image__error .el-image {
  width: 100%;
  height: 200px;
}
</style>
